package server.main;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

import android.app.Activity;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class VideoServer extends Activity implements SurfaceHolder.Callback {
	private TextView mText;
	private TextView status;
	private SurfaceView mSurface;
	private SurfaceHolder Holder;
	static MediaRecorder mRecorder = null;
	private Button start;
	private Button stop;
	private Button record;
	
	/**for LogCat filter*/
	private String TAG = "DEBUG";
	private String FilePath = null; 
	private boolean isPreview = false;
	private boolean isRecord = false;
	private LocalStreamPipe streamPipe = null;

	private FileOutputStream fos = null;
	private Thread t;
	private FileOutputStream f;
	RtspServer s = null;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mText = (TextView)findViewById(R.id.myTextView1);
        mText.setText(getLocalIpAddress());
        status = (TextView)findViewById(R.id.myTextView2);
        status.setText("ready");
        
        start = (Button)findViewById(R.id.start);
		stop = (Button)findViewById(R.id.stop);
		record = (Button)findViewById(R.id.record);
		
		mSurface = (SurfaceView)findViewById(R.id.mSurface);
		Holder = mSurface.getHolder();
		Holder.addCallback(this);
		Holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		
		/**set start button click event*/
		start.setOnClickListener(new Button.OnClickListener(){
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				startPreview();
			}
		});

		/**set stop button click event*/
		stop.setOnClickListener(new Button.OnClickListener(){
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				release();
			}
		});

		/**set record button click event*/
		record.setOnClickListener(new Button.OnClickListener(){
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				if(!isRecord){
					startRecord();
				}
			}
		});
    }
    
    private void startPreview(){

		if(!isPreview){

			if(mRecorder==null){     
				mRecorder = new MediaRecorder();
			}
	
			if(streamPipe==null){
				streamPipe = new LocalStreamPipe(100000);
			}
       
			
			mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
			
			//mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
			mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
			//mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
			mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
			//mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
			//mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
			mRecorder.setVideoSize(176,144);
			mRecorder.setOutputFile(streamPipe.getOutputFileDescriptor());
			//mRecorder.setOutputFile("/sdcard/output3.3gp");
			mRecorder.setVideoFrameRate(8);
			//mRecorder.setVideoEncodingBitRate(29);
			 
			mRecorder.setPreviewDisplay(Holder.getSurface());

			try {
				mRecorder.prepare();
			} catch(Exception e) {
				Log.e(TAG,e.toString() + "!!!!");
			}

			isPreview = true;
			status.setText("isPreview");
		}
    
	}

	private void startRecord(){
		
		
		if(isPreview){
			/**start record*/
	
			//mRecorder.start();
			isRecord = true;
	
			status.setText("isRecord");
			
			
			Log.d(TAG,"server start!!!!!!!!!");
			s = new RtspServer(streamPipe.getInputStream());
			s.start();	
            
			
			/** camera inputStream write to file */
/*
			FilePath = "/sdcard/output.3gp";
			( t = new Thread(){
				public void run(){

					InputStream fis = null;
					
				    FileOutputStream tmp = null;
					
					//fis = streamPipe.getInputStream();
					fis = streamPipe.getInputStream();
		
					//ssBufferedInputStream bs = new BufferedInputStream(fis);

					try {
						fos = new FileOutputStream(FilePath);
						
					} catch (FileNotFoundException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					int num = 0;
					byte[] buffer = new byte[1400];
					
					while(isRecord){
						try {
							num = fis.read(buffer,0,buffer.length);
							Log.d(TAG,"num = " + num);
							if(num>=0){
								fos.write(buffer,0,num);
								//fos.flush();
							}
							else{
								//file is end
								try {
									sleep(20);
								} catch (InterruptedException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
									break;
								}
							}
		               
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

					}
				}
			}).start();
*/

		}

	}

    private void release(){
    	
    	/**release MediaRecorder*/
    	if(mRecorder!=null){
			if(isRecord){
				//mRecorder.stop();
				status.setText("ready");
			}
			mRecorder.release();
			mRecorder=null;
/*
			try {
				fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
*/
            //close the thread
			if(s!=null){
				 s.finalized();
			     //s.stop();
			}
        }

		/**close local socket and inputStream*/
    	if(streamPipe!=null){
		      streamPipe.close();
		      streamPipe = null;
		}

    	/**reset*/
		isPreview = false;
		isRecord = false;
    }
    
    public static String getLocalIpAddress() {  
	    try {  
	        for (Enumeration<NetworkInterface> en = NetworkInterface  
	                .getNetworkInterfaces(); en.hasMoreElements();) {  
	            NetworkInterface intf = en.nextElement();  
	            for (Enumeration<InetAddress> enumIpAddr = intf  
	                    .getInetAddresses(); enumIpAddr.hasMoreElements();) {  
	                InetAddress inetAddress = enumIpAddr.nextElement();  
	                if (!inetAddress.isLoopbackAddress()) {  
	                    return inetAddress.getHostAddress().toString();  
	                }
	            }  
	        }  
	    } catch (SocketException ex) {  
	        Log.e("WifiPreference IpAddress", ex.toString());  
	    }  
	    return null;  
	}

	@Override
	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		
	}
}